#include "database/database_manager.h"
#include "database/disk_repository.h"
#include "database/folder_repository.h"
#include "database/file_repository.h"
#include "database/command_repository.h"
#include <stdexcept>
#include <QJsonArray>
#include <QJsonObject>
#include <QJsonValue>

DatabaseManager::DatabaseManager(QObject *parent)
    : QObject(parent)
    , m_diskRepository(nullptr)
    , m_folderRepository(nullptr)
    , m_fileRepository(nullptr)
    , m_commandRepository(nullptr)
{
    // 计算数据库路径：UserHome/.myapps/desk.db
    QString homePath = QStandardPaths::writableLocation(QStandardPaths::HomeLocation);
    m_databasePath = QDir(homePath).filePath(".myapps/desk.db");
    m_userWorkDirectory = "";
    m_currentUserId = "";
}

DatabaseManager::~DatabaseManager()
{
    delete m_diskRepository;
    delete m_folderRepository;
    delete m_fileRepository;
    delete m_commandRepository;
    
    if (m_database.isOpen()) {
        m_database.close();
    }
}

bool DatabaseManager::initializeDatabase()
{
    // 添加SQLite驱动
    if (!QSqlDatabase::drivers().contains("QSQLITE")) {
        qDebug() << "SQLite驱动不可用";
        return false;
    }

    // 确保数据库路径已计算（如果为空，则重新计算）
    if (m_databasePath.isEmpty()) {
        QString homePath = QStandardPaths::writableLocation(QStandardPaths::HomeLocation);
        m_databasePath = QDir(homePath).filePath(".myapps/desk.db");
    }
    
    // 确保数据库文件所在目录存在
    QDir dbDir = QFileInfo(m_databasePath).absoluteDir();
    if (!dbDir.exists()) {
        if (!dbDir.mkpath(".")) {
            qDebug() << "无法创建数据库目录:" << dbDir.absolutePath();
            return false;
        }
    }

    // 设置数据库连接
    m_database = QSqlDatabase::addDatabase("QSQLITE");
    m_database.setDatabaseName(m_databasePath);
    
    qDebug() << "SQLite数据库文件路径:" << m_databasePath;
    qDebug() << "数据库文件是否存在:" << QFile::exists(m_databasePath);

    // 打开数据库
    if (!m_database.open()) {
        qDebug() << "无法打开数据库:" << m_database.lastError().text();
        return false;
    }
    
    qDebug() << "SQLite数据库连接成功，实际使用的数据库文件:" << m_database.databaseName();
    qDebug() << "数据库文件创建后是否存在:" << QFile::exists(m_databasePath);

    // 创建表结构
    if (!createTables()) {
        qDebug() << "创建表失败";
        return false;
    }

    // 初始化Repository实例
    initializeRepositories();

    qDebug() << "数据库初始化成功，路径:" << m_databasePath;
    return true;
}


bool DatabaseManager::createTables()
{
    QSqlQuery query(m_database);
    
    // 创建网盘表
    QString createDiskTable = R"(
        CREATE TABLE IF NOT EXISTS kms_disk (
            ID TEXT NOT NULL,
            TYPE INTEGER DEFAULT NULL,
            NAME TEXT DEFAULT NULL,
            DOMAIN_ID TEXT DEFAULT NULL,
            OWNER_ID TEXT DEFAULT NULL,
            ORDER_NO INTEGER DEFAULT NULL,
            USER_ID TEXT DEFAULT NULL,
            PRIMARY KEY (ID)
        )
    )";
    
    if (!query.exec(createDiskTable)) {
        qDebug() << "创建网盘表失败:" << query.lastError().text();
        return false;
    }
    qDebug() << "网盘表创建成功";
    
    // 创建文件夹表
    QString createFolderTable = R"(
        CREATE TABLE IF NOT EXISTS kms_folder (
            ID TEXT NOT NULL,
            NAME TEXT DEFAULT NULL,
            DISK_ID TEXT DEFAULT NULL,
            FOLDER_ID TEXT DEFAULT NULL,
            PATH TEXT DEFAULT NULL,
            CREATOR TEXT DEFAULT NULL,
            CREATOR_ID TEXT DEFAULT NULL,
            TYPE INTEGER DEFAULT NULL,
            CREATE_DATE TEXT DEFAULT NULL,
            LAST_MODIFY_DATE TEXT DEFAULT NULL,
            ORDER_NO INTEGER DEFAULT NULL,
            REMOVE_OPERATOR TEXT DEFAULT NULL,
            STATUS INTEGER DEFAULT 0,
            VERSION INTEGER DEFAULT 0,
            MAX_VERSION INTEGER DEFAULT 0,
            USER_ID TEXT DEFAULT NULL,
            PRIMARY KEY (ID)
        )
    )";
    
    if (!query.exec(createFolderTable)) {
        qDebug() << "创建文件夹表失败:" << query.lastError().text();
        return false;
    }
    qDebug() << "文件夹表创建成功";
    
    // 创建文件表
    QString createFileTable = R"(
        CREATE TABLE IF NOT EXISTS kms_file (
            ID TEXT NOT NULL,
            NAME TEXT DEFAULT NULL,
            DISK_ID TEXT DEFAULT NULL,
            FOLDER_ID TEXT DEFAULT NULL,
            CREATOR TEXT DEFAULT NULL,
            CREATOR_ID TEXT DEFAULT NULL,
            TYPE TEXT DEFAULT NULL,
            CREATE_DATE TEXT DEFAULT NULL,
            LAST_MODIFY_DATE TEXT DEFAULT NULL,
            ORIGIN_TYPE INTEGER DEFAULT NULL,
            ORIGIN_ID TEXT DEFAULT NULL,
            SIZE INTEGER DEFAULT NULL,
            REMOVE_OPERATOR TEXT DEFAULT NULL,
            STATUS INTEGER DEFAULT 0,
            CHECKSUM TEXT DEFAULT NULL,
            LOCAL_FILE_SIZE INTEGER DEFAULT 0,
            LOCAL_FILE_CHECKSUM TEXT DEFAULT NULL,
            LOCAL_FILE_PATH TEXT DEFAULT NULL,
            VERSION INTEGER DEFAULT 0,
            USER_ID TEXT DEFAULT NULL,
            PRIMARY KEY (ID)
        )
    )";
    
    if (!query.exec(createFileTable)) {
        qDebug() << "创建文件表失败:" << query.lastError().text();
        return false;
    }
    qDebug() << "文件表创建成功";
    
    // 创建命令表
    QString createCommandTable = R"(
        CREATE TABLE IF NOT EXISTS kms_command (
            ID TEXT NOT NULL,
            COMMAND TEXT DEFAULT NULL,
            PARAMS TEXT DEFAULT NULL,
            CREATE_DATE TEXT DEFAULT NULL,
            LAST_MODIFY_DATE TEXT DEFAULT NULL,
            STATUS TEXT DEFAULT 'PENDING',
            PRIMARY KEY (ID)
        )
    )";
    
    if (!query.exec(createCommandTable)) {
        qDebug() << "创建命令表失败:" << query.lastError().text();
        return false;
    }
    qDebug() << "命令表创建成功";
    
    qDebug() << "所有数据表创建完成";
    return true;
}

bool DatabaseManager::isDatabaseConnected()
{
    return m_database.isOpen() && m_database.isValid();
}

void DatabaseManager::setCurrentUserId(const QString &userId)
{
    m_currentUserId = userId;
    qDebug() << "设置当前用户ID:" << m_currentUserId;
    
    // 更新Repository的用户ID
    if (m_diskRepository) {
        delete m_diskRepository;
        m_diskRepository = new DiskRepository(m_database, m_currentUserId);
    }
    if (m_folderRepository) {
        delete m_folderRepository;
        m_folderRepository = new FolderRepository(m_database, m_currentUserId);
    }
    if (m_fileRepository) {
        delete m_fileRepository;
        m_fileRepository = new FileRepository(m_database, m_currentUserId);
    }
}

void DatabaseManager::initializeRepositories()
{
    m_diskRepository = new DiskRepository(m_database, m_currentUserId);
    m_folderRepository = new FolderRepository(m_database, m_currentUserId);
    m_fileRepository = new FileRepository(m_database, m_currentUserId);
    m_commandRepository = new CommandRepository(m_database);
}

DiskRepository* DatabaseManager::diskRepository() const
{
    return m_diskRepository;
}

FolderRepository* DatabaseManager::folderRepository() const
{
    return m_folderRepository;
}

FileRepository* DatabaseManager::fileRepository() const
{
    return m_fileRepository;
}

CommandRepository* DatabaseManager::commandRepository() const
{
    return m_commandRepository;
}

// 网盘记录操作
bool DatabaseManager::insertDisk(const KmsDisk &disk)
{
    if (!m_diskRepository) {
        qDebug() << "DiskRepository未初始化";
        return false;
    }
    return m_diskRepository->insert(disk);
}

bool DatabaseManager::updateDisk(const KmsDisk &disk)
{
    if (!m_diskRepository) {
        qDebug() << "DiskRepository未初始化";
        return false;
    }
    return m_diskRepository->update(disk);
}

QList<KmsDisk> DatabaseManager::queryDisksByName(const QString &name)
{
    if (!m_diskRepository) {
        qDebug() << "DiskRepository未初始化";
        return QList<KmsDisk>();
    }
    return m_diskRepository->findByName(name);
}

QList<KmsDisk> DatabaseManager::queryAllDisks()
{
    if (!m_diskRepository) {
        qDebug() << "DiskRepository未初始化";
        return QList<KmsDisk>();
    }
    return m_diskRepository->findAll();
}

// 文件夹记录操作
bool DatabaseManager::insertFolder(const KmsFolder &folder)
{
    if (!m_folderRepository) {
        qDebug() << "FolderRepository未初始化";
        return false;
    }
    return m_folderRepository->insert(folder);
}

bool DatabaseManager::updateFolder(const KmsFolder &folder)
{
    if (!m_folderRepository) {
        qDebug() << "FolderRepository未初始化";
        return false;
    }
    return m_folderRepository->update(folder);
}

QList<KmsFolder> DatabaseManager::queryFoldersByPath(const QString &path)
{
    if (!m_folderRepository) {
        qDebug() << "FolderRepository未初始化";
        return QList<KmsFolder>();
    }
    return m_folderRepository->findByPath(path);
}

KmsFolder DatabaseManager::queryFolderByExactPath(const QString &path)
{
    if (!m_folderRepository) {
        qDebug() << "FolderRepository未初始化";
        return KmsFolder();
    }
    return m_folderRepository->findByExactPath(path);
}

KmsFolder DatabaseManager::queryFolderById(const QString &folderId)
{
    if (!m_folderRepository) {
        qDebug() << "FolderRepository未初始化";
        return KmsFolder();
    }
    return m_folderRepository->findById(folderId);
}

bool DatabaseManager::deleteFolder(const QString &folderId)
{
    if (!m_folderRepository) {
        qDebug() << "FolderRepository未初始化";
        return false;
    }
    return m_folderRepository->remove(folderId);
}

QList<KmsFolder> DatabaseManager::queryAllFolders()
{
    if (!m_folderRepository) {
        qDebug() << "FolderRepository未初始化";
        return QList<KmsFolder>();
    }
    return m_folderRepository->findAll();
}

// 文件记录操作
bool DatabaseManager::insertFile(const KmsFile &file)
{
    if (!m_fileRepository) {
        qDebug() << "FileRepository未初始化";
        return false;
    }
    return m_fileRepository->insert(file);
}

bool DatabaseManager::updateFile(const KmsFile &file)
{
    if (!m_fileRepository) {
        qDebug() << "FileRepository未初始化";
        return false;
    }
    return m_fileRepository->update(file);
}

QList<KmsFile> DatabaseManager::queryFilesByPath(const QString &path)
{
    if (!m_fileRepository) {
        qDebug() << "FileRepository未初始化";
        return QList<KmsFile>();
    }
    return m_fileRepository->findByPath(path);
}

QList<KmsFile> DatabaseManager::queryFilesByFolderId(const QString &folderId)
{
    if (!m_fileRepository) {
        qDebug() << "FileRepository未初始化";
        return QList<KmsFile>();
    }
    return m_fileRepository->findByFolderId(folderId);
}

QList<KmsFile> DatabaseManager::queryAllFiles()
{
    if (!m_fileRepository) {
        qDebug() << "FileRepository未初始化";
        return QList<KmsFile>();
    }
    return m_fileRepository->findAll();
}

KmsFile DatabaseManager::queryFileById(const QString &fileId)
{
    if (!m_fileRepository) {
        qDebug() << "FileRepository未初始化";
        return KmsFile();
    }
    return m_fileRepository->findById(fileId);
}

KmsFile DatabaseManager::queryFileByLocalFilePath(const QString &localFilePath)
{
    if (!m_fileRepository) {
        qDebug() << "FileRepository未初始化";
        return KmsFile();
    }
    return m_fileRepository->findByLocalFilePath(localFilePath);
}

bool DatabaseManager::deleteFile(const QString &fileId)
{
    if (!m_fileRepository) {
        qDebug() << "FileRepository未初始化";
        return false;
    }
    return m_fileRepository->remove(fileId);
}

bool DatabaseManager::updateFileFromJson(const QJsonObject &fileData)
{
    if (!m_fileRepository) {
        qDebug() << "FileRepository未初始化";
        return false;
    }
    return m_fileRepository->updateFromJson(fileData);
}

bool DatabaseManager::syncDisksFromJson(const QJsonArray &disksData)
{
    if (!m_diskRepository) {
        qDebug() << "DiskRepository未初始化";
        return false;
    }
    return m_diskRepository->syncFromJson(disksData);
}

bool DatabaseManager::syncFoldersFromJson(const QJsonArray &foldersData)
{
    if (!m_folderRepository) {
        qDebug() << "FolderRepository未初始化";
        return false;
    }
    return m_folderRepository->syncFromJson(foldersData);
}

bool DatabaseManager::syncFilesFromJson(const QJsonArray &filesData)
{
    if (!m_fileRepository) {
        qDebug() << "FileRepository未初始化";
        return false;
    }
    return m_fileRepository->syncFromJson(filesData);
}

bool DatabaseManager::updateLocalFileInfo(const QString &fileId, qint64 localFileSize, const QString &localFileChecksum, const QString &localFilePath)
{
    if (!m_fileRepository) {
        qDebug() << "FileRepository未初始化";
        return false;
    }
    return m_fileRepository->updateLocalFileInfo(fileId, localFileSize, localFileChecksum, localFilePath);
}

bool DatabaseManager::clearLocalFileInfo(const QString &fileId)
{
    if (!m_fileRepository) {
        qDebug() << "FileRepository未初始化";
        return false;
    }
    return m_fileRepository->clearLocalFileInfo(fileId);
}

bool DatabaseManager::updateFileStatus(const QString &fileId, int status)
{
    if (!m_fileRepository) {
        qDebug() << "FileRepository未初始化";
        return false;
    }
    
    // 更新文件状态
    bool result = m_fileRepository->updateStatus(fileId, status);
    if (!result) {
        return false;
    }
    
    // 查找父文件夹并更新父文件夹状态
    KmsFile file = m_fileRepository->findById(fileId);
    if (!file.id.isEmpty() && !file.folderId.isEmpty()) {
        // 找到父文件夹，执行状态更新
        qDebug() << "DatabaseManager: 找到文件的父文件夹，父文件夹ID:" << file.folderId;
        caculateAndUpdateFolderStatus(file.folderId);
    } else {
        qDebug() << "DatabaseManager: 文件没有父文件夹或文件不存在，无需更新父文件夹状态";
    }
    
    return result;
}


// 文件夹状态管理方法实现

QList<KmsFolder> DatabaseManager::querySubFoldersByFolderId(const QString &folderId)
{
    if (!m_folderRepository) {
        qDebug() << "FolderRepository未初始化";
        return QList<KmsFolder>();
    }
    return m_folderRepository->findSubFoldersByFolderId(folderId);
}

QList<KmsFile> DatabaseManager::querySubFilesByFolderId(const QString &folderId)
{
    if (!m_folderRepository) {
        qDebug() << "FolderRepository未初始化";
        return QList<KmsFile>();
    }
    return m_folderRepository->findSubFilesByFolderId(folderId);
}

bool DatabaseManager::updateFolderStatus(const QString &folderId, int status)
{
    if (!m_folderRepository) {
        qDebug() << "FolderRepository未初始化";
        return false;
    }
    
    // 更新当前文件夹状态
    bool result = m_folderRepository->updateStatus(folderId, status);
    if (!result) {
        return false;
    }
    
    // 查找父文件夹并更新父文件夹状态
    KmsFolder folder = m_folderRepository->findById(folderId);
    if (!folder.id.isEmpty() && !folder.folderId.isEmpty() && folder.folderId != "root") {
        // 找到父文件夹，执行状态更新
        qDebug() << "DatabaseManager: 找到父文件夹，父文件夹ID:" << folder.folderId;
        caculateAndUpdateFolderStatus(folder.folderId);
    } else {
        qDebug() << "DatabaseManager: 文件夹为根文件夹或没有父文件夹，无需更新父文件夹状态";
    }
    
    return result;
}

bool DatabaseManager::caculateAndUpdateFolderStatus(const QString &folderId) {
    if (folderId.isEmpty()) {
        qDebug() << "DatabaseManager: 文件夹ID为空，无法更新文件夹状态";
        return false;
    }
    
    if (!m_folderRepository) {
        qDebug() << "DatabaseManager: FolderRepository未初始化";
        return false;
    }
    
    // 查询当前文件夹
    KmsFolder folder = m_folderRepository->findById(folderId);
    if (folder.id.isEmpty()) {
        qDebug() << "DatabaseManager: 未找到文件夹，文件夹ID:" << folderId;
        return false;
    }
    
    // 查找所有子文件夹的 status
    QList<KmsFolder> subFolders = m_folderRepository->findSubFoldersByFolderId(folderId);
    
    // 查找所有子文件的 status
    QList<KmsFile> subFiles = m_folderRepository->findSubFilesByFolderId(folderId);
    
    // 初始化新状态为 0
    int newStatus = 0;
    
    // 将所有子文件夹的 status 进行按位或计算
    for (const KmsFolder &subFolder : subFolders) {
        newStatus |= subFolder.status;
    }
    
    // 将所有子文件的 status 进行按位或计算
    for (const KmsFile &subFile : subFiles) {
        newStatus |= subFile.status;
    }
    
    qDebug() << "DatabaseManager: 计算文件夹状态，文件夹ID:" << folderId 
             << "子文件夹数量:" << subFolders.size() 
             << "子文件数量:" << subFiles.size()
             << "计算后的状态:" << newStatus;
    
    // 将所有按位或计算结果通过 updateFolderStatus 更新 kms_folder.status
    bool result = updateFolderStatus(folderId, newStatus);
    
    return result;
}

// 命令记录操作
bool DatabaseManager::insertCommand(const KmsCommand &command)
{
    if (!m_commandRepository) {
        qDebug() << "CommandRepository未初始化";
        return false;
    }
    return m_commandRepository->insert(command);
}

bool DatabaseManager::updateCommandLocalFilePath(const QString &downloadUrl, const QString &localFilePath)
{
    if (!m_commandRepository) {
        qDebug() << "CommandRepository未初始化";
        return false;
    }
    return m_commandRepository->updateLocalFilePath(downloadUrl, localFilePath);
}

KmsCommand DatabaseManager::queryCommandByLocalFilePath(const QString &localFilePath)
{
    if (!m_commandRepository) {
        qDebug() << "CommandRepository未初始化";
        return KmsCommand();
    }
    return m_commandRepository->findByLocalFilePath(localFilePath);
}

KmsCommand DatabaseManager::queryCommandByLocalFilePathAndCommand(const QString &localFilePath, const QString &command)
{
    if (!m_commandRepository) {
        qDebug() << "CommandRepository未初始化";
        return KmsCommand();
    }
    return m_commandRepository->findByLocalFilePathAndCommand(localFilePath, command);
}

KmsCommand DatabaseManager::queryCommandByDownloadUrl(const QString &downloadUrl)
{
    if (!m_commandRepository) {
        qDebug() << "CommandRepository未初始化";
        return KmsCommand();
    }
    return m_commandRepository->findByDownloadUrl(downloadUrl);
}

bool DatabaseManager::deleteCommandByCommitUrl(const QString &commitUrl)
{
    if (!m_commandRepository) {
        qDebug() << "CommandRepository未初始化";
        return false;
    }
    return m_commandRepository->removeByCommitUrl(commitUrl);
}

bool DatabaseManager::updateCommandStatusByCommitUrl(const QString &commitUrl, const QString &command, const QString &status)
{
    if (!m_commandRepository) {
        qDebug() << "CommandRepository未初始化";
        return false;
    }
    return m_commandRepository->updateStatusByCommitUrl(commitUrl, command, status);
}

bool DatabaseManager::updateCommandStatusByDownloadUrl(const QString &downloadUrl, const QString &command, const QString &status)
{
    if (!m_commandRepository) {
        qDebug() << "CommandRepository未初始化";
        return false;
    }
    return m_commandRepository->updateStatusByDownloadUrl(downloadUrl, command, status);
}
